package com.sample.springbatch.service;

/**
 * 
 * @author niqinqin
 *
 */
public abstract class Luhn {

	private static String getDigitsOnly(String s) {
		StringBuffer digitsOnly = new StringBuffer();
		char c;
		for (int i = 0; i < s.length(); i++) {
			c = s.charAt(i);
			if (Character.isDigit(c)) {
				digitsOnly.append(c);
			}
		}
		return digitsOnly.toString();
	}

	// -------------------
	// Perform Luhn check
	// -------------------

	public static boolean isValid(String cardNumber) {
		String digitsOnly = getDigitsOnly(cardNumber);
		int sum = 0;
		int digit = 0;
		int addend = 0;
		boolean timesTwo = false;

		for (int i = digitsOnly.length() - 1; i >= 0; i--) {
			digit = Integer.parseInt(digitsOnly.substring(i, i + 1));
			if (timesTwo) {
				addend = digit * 2;
				if (addend > 9) {
					addend -= 9;
				}
			} else {
				addend = digit;
			}
			sum += addend;
			timesTwo = !timesTwo;
		}

		int modulus = sum % 10;
		return modulus == 0;
	}

	/**
	 * @param LuhnNbr 通过Luhn算法计算最后一位校验位的值，传入的LuhnNbr最后一位必须是0，否则不准确
	 * @return 一个可以通过Luhn校验算法的Long值
	 */
	public static Long getLuhnId(String LuhnNbr) {
		String digitsOnly = getDigitsOnly(LuhnNbr);
		if(!('0' == digitsOnly.charAt(digitsOnly.length() - 1))) {
			throw new RuntimeException("MustBeEndOfZero: "+digitsOnly);
		}
		int sum = 0;
		int digit = 0;
		int addend = 0;
		boolean timesTwo = false;

		for (int i = digitsOnly.length() - 1; i >= 0; i--) {
			digit = Integer.parseInt(digitsOnly.substring(i, i + 1));
			if (timesTwo) {
				addend = digit * 2;
				if (addend > 9) {
					addend -= 9;
				}
			} else {
				addend = digit;
			}
			sum += addend;
			timesTwo = !timesTwo;
		}
		int modulus = sum % 10;
		if(modulus == 0) {
			return Long.parseLong(digitsOnly);
		}else {
			return Long.parseLong(digitsOnly)+(10 - modulus);
		}
	}
	
	
	public static String getLuhnIdStr(String LuhnNbr) {
		String digitsOnly = getDigitsOnly(LuhnNbr);
		if(!('0' == digitsOnly.charAt(digitsOnly.length() - 1))) {
			throw new RuntimeException("MustBeEndOfZero: "+digitsOnly);
		}
		int sum = 0;
		int digit = 0;
		int addend = 0;
		boolean timesTwo = false;

		for (int i = digitsOnly.length() - 1; i >= 0; i--) {
			digit = Integer.parseInt(digitsOnly.substring(i, i + 1));
			if (timesTwo) {
				addend = digit * 2;
				if (addend > 9) {
					addend -= 9;
				}
			} else {
				addend = digit;
			}
			sum += addend;
			timesTwo = !timesTwo;
		}
		int modulus = sum % 10;
		StringBuffer sb = new StringBuffer();
		if(modulus == 0) {
			return digitsOnly;
		}else {
			return sb.append(digitsOnly.substring(0, 18)).append((10 - modulus)).toString();
		}
	}

}
